(function() {
    Nokia.Sortable = Nokia.Widget.extend({
        initialize: function(options) {
            var instance = this;

			var defaults = {
				items: '> div',
				selectedClass: 'selected',
				resetInterval: 300
            };

            instance.options = jQuery.extend(defaults, options);

            instance.element = jQuery( instance.options.element );

            instance._super.apply(instance, [instance.options]);

			instance.selectedOriginal = null;
			instance.selectedTarget = null;

			instance._create();

			instance.registerVibrationOn([ 'select' ]);

			instance._attachEvents();

			instance.fireCallback('create');
        },

		_attachEvents: function() {
			var instance = this;
			var options = instance.options;
			var Styles = instance.Styles;

			var select = function(event) {
				var item = jQuery(event.target);

				instance.select(item, event);
			};

			var clear = function() {
				instance.clear();
			};

			var reset = function(event) {
				var container =  instance.element[0];

				// jQuery bug - restoring undefined last toggle
				this.lastToggle = undefined;

				if (event.target == container) {
					instance.clear();
					instance._attachEvents();

					instance.fireCallback('reset', event);
					return false;
				}
			};

			instance.element.unbind('toggle');
			instance.element.unbind('click');
			instance.element.unbind('click.reset');

			instance.element.bind('click.reset', reset);
			instance.element.toggle(select, select, clear);

			Nokia.util.bindEnter(instance.element, select);

			jQuery(options.items, instance.element).hover(function() {
				jQuery(this).addClass(Styles.uiStateHover);
			}, function() {
				jQuery(this).removeClass(Styles.uiStateHover);
			});
		},

		select: function(item, event) {
			var instance = this;
			var options = instance.options;
			var selectedClass = '.' + options.selectedClass;
			var selected = item.is(selectedClass);

			if (selected) {
				// clear if the click is on the last selected
				instance.element.trigger('click.reset');
			}
			else {
				Nokia.util.addClass(item[0], options.selectedClass);

				var selectedItems = instance.element.find(selectedClass);
				var totalSelected = selectedItems.length;

				if (totalSelected == 1) {
					instance.selectedOriginal = item;
				}
				else if (totalSelected == 2) {
					instance.selectedTarget = item;
				}

				var original = instance.selectedOriginal;
				var target = instance.selectedTarget;

				instance.fireCallback('select', event, original, target);

				if (original && target) {

					Nokia.animation.prepareForTransition();

					instance.changePosition(event);

					Nokia.animation.performTransition();
				}
			}
		},

		getSelectedElements: function() {
			var instance = this;

			return [ instance.selectedOriginal, instance.selectedTarget ];
		},

		clear: function(item) {
			var instance = this;
			var options = instance.options;
			var Styles = instance.Styles;

			instance.selectedOriginal = null;
			instance.selectedTarget = null;

			if (!item) {
				item = instance.element.find(options.items);
			}

			jQuery(item).removeClass([options.selectedClass, Styles.uiStateHover].join(' '));
		},

		changePosition: function(event) {
			var instance = this;
			var options = instance.options;
			var original = instance.selectedOriginal;
			var placeholder = instance.placeholder;
			var target = instance.selectedTarget;

			Nokia.dom.insertAfter(original, placeholder);

			Nokia.dom.insertAfter(target, original);

			Nokia.dom.insertAfter(placeholder, target);

			placeholder.remove();

			var clear = function() {
				instance.element.trigger('click.reset');
			};

			setTimeout(clear, options.resetInterval);

			instance.fireCallback('change', event, original, target);
		},

		_create: function() {
			var instance = this;
			var options = instance.options;

			instance.placeholder = Nokia.dom.parseHTML('<div class="nokia-sortable-placeholder"></div>')

			instance.element.addClass(instance.Styles.sortable);
		},

		Styles: {
			sortable: 'nokia-sortable',
			uiStateHover: 'ui-state-hover'
		}
    });
})();